/**
 * @author 艾尼亚尔
 * @date 2025/5/19
 * @description
 */
import axios from 'axios';
import type {AxiosInstance, AxiosResponse, AxiosRequestConfig} from 'axios';
import type {CreateAxiosOptions, Result} from "./help.ts";
import {cloneDeep} from "lodash";
import {isFunction} from './help.ts'

export class AxiosService {
    private axiosInstance: AxiosInstance;
    private readonly transform?: AxiosTransform;
    private readonly options: CreateAxiosOptions;

    constructor(options: CreateAxiosOptions) {
        this.transform = options.transform;
        this.options = options;
        this.axiosInstance = axios.create(options);
        this.setupInterceptors();
    }
    private setupInterceptors() {
        // 请求拦截器
        this.axiosInstance.interceptors.request.use(
            (config) => {
                if (this.transform?.beforeRequest) {
                    return this.transform.beforeRequest(config) || config;
                }
                return config;
            },
            (error) => {
                if (this.transform?.requestError) {
                    return this.transform.requestError(error) || Promise.reject(error);
                }
                return Promise.reject(error);
            }
        );
        // 响应拦截器
        this.axiosInstance.interceptors.response.use(
            (response) => {
                if (this.transform?.beforeResponse) {
                    return this.transform.beforeResponse(response) || response.data;
                }
                return response.data;
            },
            (error) => {
                if (this.transform?.responseError) {
                    return this.transform.responseError(error) || Promise.reject(error);
                }
                return Promise.reject(error);
            }
        );
    }

    request<T = any>(config: AxiosRequestConfig): Promise<T> {
        let conf: AxiosRequestConfig = cloneDeep(config);
        console.log(conf)
        const {beforeRequestHook, transformResponseData, requestCatch} = this.transform || {};
        const { transform, ...opt } = this.options;
        if (beforeRequestHook && isFunction(beforeRequestHook)) {
            conf = beforeRequestHook(conf, opt);
        }
        return new Promise((resolve, reject) => {
            this.axiosInstance
                .request<any, AxiosResponse<Result>>(conf)
                .then((res: AxiosResponse<Result>) => {
                    // 请求是否被取消
                    const isCancel = axios.isCancel(res);
                    if (transformResponseData && isFunction(transformResponseData) && !isCancel) {
                        try {
                            const ret = transformResponseData(res, opt);
                            resolve(ret);
                        } catch (err) {
                            reject(err || new Error('request error!'));
                        }
                        return;
                    }
                    resolve(res as unknown as Promise<T>);
                })
                .catch((e: Error) => {
                    if (requestCatch && isFunction(requestCatch)) {
                        reject(requestCatch(e));
                        return;
                    }
                    reject(e);
                });
        });
    }
}